package algorithm.sphericharmonics;

import algorithm.fft.Complex;


public final class LongitudeCircle {
	private float latAngle;
	public IntList lngAngles=new IntList(); 
	private float delta_phi=0; 
	private int index; 
	private int numberOfGrid;
	public static final float TWOPI=(float)(2*Math.PI); 
	public final ScaledAssociatedLagendrePolynomial[] qFunctions=new ScaledAssociatedLagendrePolynomial[VoxelizedSphere.lmax+1]; 
	public LongitudeCircle(float latAngle,int numOfGrid, int index){
		this.latAngle=latAngle;
		this.numberOfGrid=numOfGrid; 
		delta_phi=TWOPI/this.numberOfGrid;  
		this.index=index; 
		for (int i=0; i<VoxelizedSphere.lmax; i++){
			qFunctions[i]=new ScaledAssociatedLagendrePolynomial(i,(float)Math.cos(latAngle));
			qFunctions[i].precompute(); 
		}
	}
	public int getIndex(){
		return index; 
	}
	public final float getDeltaPhi(){
		return delta_phi; 
	}
	public final float[] getQValues(int m){
		return qFunctions[m].qValues;  
	}
	public final float getValue(int l,int m){
		if (m>=0){
			return qFunctions[m].getPositiveValue(l);
		}else {
			if (m%2==0){
				return qFunctions[-m].getPositiveValue(l); 
			}else {
				return -qFunctions[-m].getPositiveValue(l);
			} 
		}
	}
	public float getLatAngle() {
		return latAngle;
	}
	public void setLatAngle(float latAngle) {
		this.latAngle = latAngle;
	}
	public final IntList getLngAngles() {
		return lngAngles;
	}
	public void setLngAngles(IntList lngAngles) {
		this.lngAngles = lngAngles;
	}
	public float getAngleAt(int index){
		return this.delta_phi*index; 
	}
	/*
	public void add(float phi){
		this.lngAngles.add((int)(phi/delta_phi)); 
	}
	*/
	public final void add(int index_phi){
		this.lngAngles.add(index_phi); 
	}
	public static void test(){
		LongitudeCircle ll=null; 
		for (int k=0; k<180;k++){
			System.out.println("k:"+k); 
			float theta=k*(float)Math.PI/180.f;
			ll=new LongitudeCircle(theta,180,0);
			for (int l=0; l<=4; l++){
				float f=(float)Math.sqrt((2*l+1)/Math.PI)/2;
				for (int m=0; m<=l; m++){
					ComplexSphere c1=SphericalHarmonics.yfunct(l, m, theta, 0); 
					float v=ll.getValue(l, m)*f; 
					Complex cv=new Complex(v,0); 
					Complex c=c1.toComplex(); 
					double diff=Math.abs(c.re-cv.re)+Math.abs(c.im-cv.im); 
					if (diff>1.0e-5){
						System.out.println("********  l="+l+", m="+m+" ***********");
						System.out.println(c1+"=="+v);
					}
				}
			}
		}
	}
	
	public static void main(String[] args){
		test(); 
	}
}
